<?php
declare (strict_types=1);

namespace addons\Gallery\driver;

use Qiniu\Auth;
use think\App;
use think\Exception;
use think\facade\Db;
use think\facade\View;
use think\Response;
use app\common\tool\Result;

class Gallery
{

    /**
     * @var string 错误信息
     */
    public string $error;

    /**
     * @var string 配置文件
     */
    public array $config;

    /**
     * @var object|\think\Request
     */
    public object $request;

    /**
     * @var object|App
     */
    public object $app;

    /**
     * @var string 图库表
     */
    public string $db = 'addons_gallery';

    /**
     * @var string 图库分类表
     */
    public string $cate = 'addons_gallery_cate';

    public array $titles = [1 => '图片', 2 => '视频'];

    public function __construct(App $app)
    {
        $this->config = config('gallery');
        if (empty($this->config)) {
            throw new Exception('缺少配置参数：gallery.php');
        }
        $this->app = $app;
        $this->request = $this->app->request;
    }

    public function index(): Response
    {
        $param = $this->request->get();
        $that = Db::name($this->db)->where(['status' => 1, 'delete_time' => 0, 'cate' => $param['cate']])
            ->page(intval($param['page']), intval($param['limit']))->order('create_time', 'desc');
        if (isset($param['keyword']) && $param['keyword']) {
            $that->whereLike('title', '%' . $param['keyword'] . '%');
        }
        $count = Db::name($this->db)->where(['status' => 1, 'delete_time' => 0, 'cate' => $param['cate']])->count();

        $data = $that->select()->each(function ($callback) {
            $callback['url'] = $callback['type'] == 1 ? $callback['url'] : $this->config['qiniu']['domain'] . $callback['url'];
            return $callback;
        });

        return Result::fastReturn(['code' => 0, 'data' => $data, 'count' => $count]);
    }

    public function open(): string
    {
        $param = $this->request->get();
        $cate = Db::name($this->cate)->where(['status' => 1, 'delete_time' => 0, 'type' => $param['t']])->field('id,title')->select();
        $cateId = !$cate->isEmpty() ? $cate[0]['id'] : 0;
        return View::assign([
            'type'   => $param['t'],
            'title'  => $this->titles[$param['t']],
            'cate'   => $cate,
            'param'  => $param,
            'spec'      => !empty($param['spec']) ? $param['spec'] : '',
            'editor' => isset($param['editor']) && $param['editor'] ? $param['editor'] : "",
            'count'  => $cateId ? Db::name($this->db)->where(['status' => 1, 'delete_time' => 0, 'cate' => $cateId])->count() : 0,
            'qiNiu'  => [
                'open'  => $this->config['qiniu']['open'],
                'url'   => $this->config['qiniu']['uploadUrl'],
                'token' => $this->config['qiniu']['open'] ? $this->getQnToken() : ''
            ]
        ])->fetch($this->app->getRootPath() . 'addons/Gallery/view/open.html');
    }


    public function destroy(): Response
    {
        try {
            $param = $this->request->post();
            $list = Db::name($this->db)->whereIn('id', $param['id'])->select();
            if ($list->isEmpty()) {
                return Result::fail('删除失败');
            }
            foreach ($list as $info) {
                if ($info['type'] == 1) {
                    if (file_exists('.' . $info['url'])) {
                        unlink('.' . $info['url']);
                    }
                } else {
                    $this->deleteQiNiu($info['url']);
                }

            }
            Db::name($this->db)->whereIn('id', $param['id'])->delete();
            return Result::success('已删除');
        } catch (\Exception $e) {
            return Result::fail('删除失败：' . $e->getMessage());
        }
    }

    public function addGroup(): Response
    {
        $param = $this->request->post();
        $param['create_time'] = date('Y-m-d H:i:s');
        $param['update_time'] = date('Y-m-d H:i:s');
        Db::name($this->cate)->insert($param);
        return Result::success('添加成功');
    }

    public function saveGroup(): Response
    {
        Db::name($this->cate)->update($this->request->post());
        return Result::success('已修改');
    }

    public function destroyGroup(): Response
    {
        try {
            $param = $this->request->post();
            $info = Db::name($this->cate)->where('id', $param['id'])->find();

            if (empty($info)) {
                return Result::fail('删除失败,分组不存在');
            }
            $list = Db::name($this->db)->where('cate', $info['id'])->select();
            foreach ($list as $k => $v) {
                if ($v['type'] == 1) {
                    if (file_exists('.' . $v['url'])) {
                        unlink('.' . $v['url']);
                    }
                } else {
                    $this->deleteQiNiu($v['url']);
                }
            }
            Db::name($this->db)->whereIn('cate', $info['id'])->delete();
            Db::name($this->cate)->where('id', $param['id'])->delete();
            return Result::success('已删除');
        } catch (\Exception $e) {
            return Result::fail('删除失败：' . $e->getMessage());
        }
    }


    public function upload(): Response
    {
        try {
            $file = request()->file();
            $type = request()->param('type');
            if ($type == 1) {
                validate(['file' => 'filesize:' . $this->config['image']['filesize'] . '|fileExt:' . $this->config['image']['fileExt'] . ''],
                    [
                        'file.filesize' => '文件太大',
                        'file.fileExt' => '文件格式不正确',
                    ])->check($file);
                $result = (new Compress($this->config['image']))->compressImg($file);
            } else {
                validate(['file' => 'filesize:' . $this->config['video']['filesize'] . '|fileExt:' . $this->config['video']['fileExt'] . ''],
                    [
                        'file.filesize' => '文件太大',
                        'file.fileExt' => '文件格式不正确',
                    ])->check($file);
                $result = (new Compress($this->config['video']))->compressVideo($file);
            }
            if ($result['code'] != 1) return Result::fail($result['msg']);

            Db::name($this->db)->insert([
                'title'       => $result['result']['name'],
                'url'         => $result['result']['url'],
                'cate'        => request()->param('cate'),
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s')
            ]);
            return Result::success('上传成功');
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    public function getQnToken(): string
    {
        try {
            $config = config('gallery')['qiniu'];
            $auth = new Auth($config['accessKey'], $config['secretKey']);
            $bucket = $config['bucket'];
            $token = $auth->uploadToken($bucket);
            return $token;
        } catch (\Exception $e) {
            return '';
        }

    }

    public function addImage()
    {
        try {
            $param = $this->request->post();
            Db::name($this->db)->insert([
                'title'       => $param['title'],
                'url'         => $param['key'],
                'cate'        => $param['cate'],
                'type'        => 2,
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s')
            ]);
            return Result::success('上传成功');
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }


    public function deleteQiNiu($key): bool
    {
        try {
            $config = $this->config['qiniu'];
            $auth = new Auth($config['accessKey'], $config['secretKey']);

            $bucketManager = new \Qiniu\Storage\BucketManager($auth, (new \Qiniu\Config()));
            $err = $bucketManager->delete($config['bucket'], $key);
            if (!$err[1]) {
                return true;
            }
            return false;
        } catch (\Exception $e) {
            return false;
        }

    }

}
